﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;

namespace Esponce.QRCode.Models
{
	[DataContract(Name = "record", Namespace = "")]
	public class Record : INotifyPropertyChanged
	{
		#region Constants
		public const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
		#endregion

		#region Public properties
		/// <summary>
		/// Gets device name: manufacturer + model name.
		/// </summary>
		public string DeviceName
		{
			get
			{
				return (this.DeviceManufacturer + " " + this.DeviceModel).Trim();
			}
		}

		/// <summary>
		/// Gets or sets device manufacturer name.
		/// </summary>
		[DataMember(Name = "manufacturer", IsRequired = false, EmitDefaultValue = false)]
		public string DeviceManufacturer
		{
			get
			{
				return this.deviceManufacturer;
			}
			set
			{
				if (this.deviceManufacturer != value)
				{
					this.deviceManufacturer = value;
					OnPropertyChanged("DeviceManufacturer");
				}
			}
		}
		private string deviceManufacturer;

		/// <summary>
		/// Gets or sets device model name.
		/// </summary>
		[DataMember(Name = "deviceModel", IsRequired = false, EmitDefaultValue = false)]
		public string DeviceModel
		{
			get
			{
				return this.deviceModel;
			}
			set
			{
				if (this.deviceModel != value)
				{
					this.deviceModel = value;
					OnPropertyChanged("DeviceModel");
				}
			}
		}
		private string deviceModel;

		/// <summary>
		/// Gets or sets platform name.
		/// </summary>
		[DataMember(Name = "systemName", IsRequired = false, EmitDefaultValue = false)]
		public string SystemName
		{
			get
			{
				return this.systemName;
			}
			set
			{
				if (this.systemName != value)
				{
					this.systemName = value;
					OnPropertyChanged("SystemName");
				}
			}
		}
		private string systemName;

		/// <summary>
		/// Gets or sets platform version.
		/// </summary>
		[DataMember(Name = "systemVersion", IsRequired = false, EmitDefaultValue = false)]
		public string SystemVersion
		{
			get
			{
				return this.systemVersion;
			}
			set
			{
				if (this.systemVersion != value)
				{
					this.systemVersion = value;
					OnPropertyChanged("SystemVersion");
				}
			}
		}
		private string systemVersion;

		/// <summary>
		/// Gets or sets application name.
		/// </summary>
		[DataMember(Name = "browserName", IsRequired = false, EmitDefaultValue = false)]
		public string BrowserName
		{
			get
			{
				return this.browserName;
			}
			set
			{
				if (this.browserName != value)
				{
					this.browserName = value;
					OnPropertyChanged("BrowserName");
				}
			}
		}
		private string browserName;

		/// <summary>
		/// Gets or sets application version.
		/// </summary>
		[DataMember(Name = "browserVersion", IsRequired = false, EmitDefaultValue = false)]
		public string BrowserVersion
		{
			get
			{
				return this.browserVersion;
			}
			set
			{
				if (this.browserVersion != value)
				{
					this.browserVersion = value;
					OnPropertyChanged("BrowserVersion");
				}
			}
		}
		private string browserVersion;

		/// <summary>
		/// Gets or sets city of scan.
		/// </summary>
		[DataMember(Name = "city", IsRequired = false, EmitDefaultValue = false)]
		public string City
		{
			get
			{
				return this.city;
			}
			set
			{
				if (this.city != value)
				{
					this.city = value;
					OnPropertyChanged("City");
				}
			}
		}
		private string city;

		/// <summary>
		/// Gets or sets two letter country code.
		/// </summary>
		[DataMember(Name = "countryCode", IsRequired = false, EmitDefaultValue = false)]
		public string CountryCode
		{
			get
			{
				return this.countryCode;
			}
			set
			{
				if (this.countryCode != value)
				{
					this.countryCode = value;
					OnPropertyChanged("CountryCode");
				}
			}
		}
		private string countryCode;

		/// <summary>
		/// Gets or sets latitude part of scan location.
		/// </summary>
		[DataMember(Name = "latitude", IsRequired = false, EmitDefaultValue = false)]
		public double? Latitude
		{
			get
			{
				return this.latitude;
			}
			set
			{
				if (this.latitude != value)
				{
					this.latitude = value;
					OnPropertyChanged("Latitude");
				}
			}
		}
		private double? latitude;

		/// <summary>
		/// Gets or sets longitude part of scan location.
		/// </summary>
		[DataMember(Name = "longitude", IsRequired = false, EmitDefaultValue = false)]
		public double? Longitude
		{
			get
			{
				return this.longitude;
			}
			set
			{
				if (this.longitude != value)
				{
					this.longitude = value;
					OnPropertyChanged("Longitude");
				}
			}
		}
		private double? longitude;

		[DataMember(Name = "created", IsRequired = false, EmitDefaultValue = false)]
		public string CreatedString
		{
			get
			{
				return (this.Created != null ? this.Created.Value.ToString(DateTimeFormat) : null);
			}
			set
			{
				DateTime result;
				if (DateTime.TryParseExact(value ?? "", DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
				{
					this.Created = result;
				}
				else
				{
					this.Created = null;
				}
			}
		}

		/// <summary>
		/// Gets or sets the timestamp of the record.
		/// </summary>
		public DateTime? Created
		{
			get
			{
				return this.created;
			}
			set
			{
				if (this.created != value)
				{
					this.created = value;
					OnPropertyChanged("Created");
					OnPropertyChanged("CreatedString");
					OnPropertyChanged("Date");
				}
			}
		}
		private DateTime? created;

		/// <summary>
		/// Gets only the date part of "Created" property.
		/// </summary>
		public DateTime? Date
		{
			get
			{
				return this.Created != null ? (DateTime?)this.Created.Value.Date : null;
			}
		}

		/// <summary>
		/// Gets or sets a value indicating whether the device is mobile device, i.e. phone or tablet
		/// </summary>
		[DataMember(Name = "isMobileDevice", IsRequired = false, EmitDefaultValue = false)]
		public bool IsMobileDevice
		{
			get
			{
				return this.isMobileDevice;
			}
			set
			{
				if (this.isMobileDevice != value)
				{
					this.isMobileDevice = value;
					OnPropertyChanged("IsMobileDevice");
				}
			}
		}
		private bool isMobileDevice;

		/// <summary>
		/// Gets or sets a value indicating whether the device is tablet.
		/// </summary>
		[DataMember(Name = "isTablet", IsRequired = false, EmitDefaultValue = false)]
		public bool IsTablet
		{
			get
			{
				return this.isTablet;
			}
			set
			{
				if (this.isTablet != value)
				{
					this.isTablet = value;
					OnPropertyChanged("IsTablet");
				}
			}
		}
		private bool isTablet;
		#endregion

		#region INotifyPropertyChanged Members
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		#endregion
	}
}
